home *** CD-ROM | disk | FTP | other *** search
- <?xml version="1.0"?>
-
- <bindings id="mailBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:nc="http://home.netscape.com/NC-rdf#"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
- <!-- dummy widget to force this file to load -->
- <binding id="dummy" extends="xul:box"/>
-
- <!-- temporary holding place for horizontal list -->
-
- <binding id="extdescription" extends="chrome://global/content/bindings/text.xml#text-base">
- <implementation implements="nsIDOMXULMultiSelectControlElement, nsIDOMXULSelectControlElement">
- <field name="_isUpSelection">0</field>
- <field name="_isDownSelection">0</field>
- <field name="_suppressOnSelect">false</field>
- <field name="_selectionStart">null</field>
- <field name="_currentItem">null</field>
- <field name="_selectTimeout">null</field>
- <field name="_lastKeyTime">0</field>
- <field name="_incrementalString">""</field>
-
- <constructor>
- <![CDATA[
- var els = this.getElementsByAttribute("selected", "true");
- this.selectedItems = [];
- for (var i = 0; i < els.length; ++i)
- this.selectedItems.push(els[i]);
- ]]>
- </constructor>
-
- <!-- ///////////////// public members ///////////////// -->
- <property name="_selectDelay"
- onset="this.setAttribute('_selectDelay', val);"
- onget="return this.getAttribute('_selectDelay') || 50;"/>
-
- <method name="timedSelect">
- <parameter name="item"/>
- <parameter name="timeout"/>
- <body>
- <![CDATA[
- var suppress = this._suppressOnSelect;
- if (timeout != -1)
- this._suppressOnSelect = true;
-
- this.selectItem(item);
-
- this._suppressOnSelect = suppress;
-
- if (timeout != -1) {
- if (this._selectTimeout)
- window.clearTimeout(this._selectTimeout);
-
- this._selectTimeout = window.setTimeout(this._selectTimeoutHandler, timeout, this);
- }
- ]]>
- </body>
- </method>
-
- <method name="appendItem">
- <parameter name="label"/>
- <body>
- <![CDATA[
- var XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
- var item = document.createElementNS(XULNS, "descriptionitem");
- item.setAttribute("label", label);
- this.appendChild(item);
- return item;
- ]]>
- </body>
- </method>
-
- <!-- ///////////////// private members ///////////////// -->
-
- <method name="_fireOnSelect">
- <body>
- <![CDATA[
- if (!this._suppressOnSelect && this.getAttribute("suppressonselect") != "true") {
- var event = document.createEvent("Events");
- event.initEvent("select", false, true);
- this.dispatchEvent(event);
- }
- ]]>
- </body>
- </method>
-
- <method name="_selectTimeoutHandler">
- <parameter name="me"/>
- <body>
- <![CDATA[
- me._fireOnSelect();
- me._selectTimeout = null;
- ]]>
- </body>
- </method>
-
- <!-- ///////////////// nsIDOMXULSelectControlElement ///////////////// -->
-
- <property name="selType"
- onget="return this.getAttribute('seltype')"
- onset="this.setAttribute('seltype', val); return val;"/>
-
- <property name="selectedIndex">
- <getter><![CDATA[
- return this.selectedItems.length > 0 ? this.getIndexOfItem(this.selectedItems[0]) : -1;
- ]]></getter>
- <setter><![CDATA[
- if (val >= 0)
- this.selectItem(this.getItemAtIndex(val));
- else
- this.clearSelection();
- ]]></setter>
- </property>
-
- <property name="selectedItem">
- <getter><![CDATA[
- return this.selectedItems.length > 0 ? this.selectedItems[0] : null;
- ]]></getter>
- <setter><![CDATA[
- this.selectItem(val);
- ]]></setter>
- </property>
-
- <!-- ///////////////// nsIDOMXULSelectMultipleControlElement ///////////////// -->
-
- <property name="currentItem" onget="return this._currentItem;">
- <setter>
- <![CDATA[
- if (this._currentItem)
- this._currentItem.removeAttribute("current");
- this._currentItem = val;
- if (val)
- val.setAttribute("current", "true");
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="selectedCount" onget="return this.selectedItems.length;"/>
-
- <method name="getSelectedItem">
- <parameter name="index"/>
- <body>
- <![CDATA[
- return index < this.selectedItems.length ? this.selectedItems[index] : null;
- ]]>
- </body>
- </method>
-
- <method name="addItemToSelection">
- <parameter name="item"/>
- <body>
- <![CDATA[
- if (this.selType != "multiple" && this.selectedCount)
- return;
- if (item.hasAttribute("selected"))
- return;
- this.selectedItems.push(item);
- item.setAttribute("selected", "true");
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="removeItemFromSelection">
- <parameter name="item"/>
- <body>
- <![CDATA[
- if (!item.hasAttribute("selected"))
- return;
-
- for (var i = 0; i < this.selectedItems.length; ++i) {
- if (this.selectedItems[i] == item) {
- this.selectedItems.splice(i, 1);
- item.removeAttribute("selected");
- break;
- }
- }
-
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="toggleItemSelection">
- <parameter name="item"/>
- <body>
- <![CDATA[
- if (item.hasAttribute("selected"))
- this.removeItemFromSelection(item);
- else
- this.addItemToSelection(item);
- ]]>
- </body>
- </method>
-
- <method name="selectItem">
- <parameter name="item"/>
- <body>
- <![CDATA[
- if (!item)
- return;
-
- if (this.selectedItems.length == 1 && this.selectedItems[0] == item)
- return;
-
- this._selectionStart = null;
-
- var suppress = this._suppressOnSelect;
- this._suppressOnSelect = true;
-
- this.clearSelection();
- this.addItemToSelection(item);
- this.currentItem = item;
-
- this._suppressOnSelect = suppress;
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="selectItemRange">
- <parameter name="startItem"/>
- <parameter name="endItem"/>
- <body>
- <![CDATA[
- if (this.selType != "multiple")
- return;
-
- if (!startItem)
- startItem = this._selectionStart ? this._selectionStart : this.currentItem;
- if (!startItem)
- startItem = endItem;
-
- var suppressSelect = this._suppressOnSelect;
- this._suppressOnSelect = true;
- this.clearSelection();
-
- this._selectionStart = startItem;
-
- var currentItem;
- var startIndex = this.getIndexOfItem(startItem);
- var endIndex = this.getIndexOfItem(endItem);
- if (endIndex < startIndex) {
- currentItem = endItem;
- endItem = startItem;
- startItem = currentItem;
- } else {
- currentItem = startItem;
- }
-
- while (currentItem) {
- if (currentItem.localName == "descriptionitem")
- this.addItemToSelection(currentItem);
- if (currentItem == endItem)
- break;
- currentItem = this.getNextItem(currentItem, 1);
- }
-
- this._suppressOnSelect = suppressSelect;
-
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="selectAll">
- <body>
- <![CDATA[
- var suppress = this._suppressOnSelect;
- this._suppressOnSelect = true;
-
- var item = this.getItemAtIndex(0);
- while (item) {
- this.addItemToSelection(item);
- item = this.getNextItem(item, 1);
- }
-
- this._suppressOnSelect = suppress;
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="invertSelection">
- <body>
- <![CDATA[
- var suppress = this._suppressOnSelect;
- this._suppressOnSelect = true;
-
- var item = this.getItemAtIndex(0);
- while (item) {
- if (item.hasAttribute("selected"))
- this.removeItemFromSelection(item);
- else
- this.addItemToSelection(item);
- item = this.getNextItem(item, 1);
- }
-
- this._suppressOnSelect = suppress;
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="clearSelection">
- <body>
- <![CDATA[
- if (this.selectedItems)
- {
- for (var i = this.selectedItems.length-1; i >= 0; --i)
- this.selectedItems[i].removeAttribute("selected");
-
- this.selectedItems.splice(0, this.selectedItems.length);
- }
- this._selectionStart = null;
- this._fireOnSelect();
- ]]>
- </body>
- </method>
-
- <method name="getNextItem">
- <parameter name="startItem"/>
- <parameter name="delta"/>
- <body><![CDATA[
- while (startItem) {
- startItem = startItem.nextSibling;
- if (startItem && startItem.localName == "descriptionitem") {
- --delta;
- if (delta == 0)
- return startItem;
- }
- }
- return null;
- ]]></body>
- </method>
-
- <method name="getPreviousItem">
- <parameter name="startItem"/>
- <parameter name="delta"/>
- <body><![CDATA[
- while (startItem) {
- startItem = startItem.previousSibling;
- if (startItem && startItem.localName == "descriptionitem") {
- --delta;
- if (delta == 0)
- return startItem;
- }
- }
- return null;
- ]]></body>
- </method>
-
- <!-- selection navigation -->
- <method name="navigateToPreviousItem">
- <parameter name="event"/>
- <body>
- <![CDATA[
- if (event.target != this)
- return;
- this._isUpSelection=0;
- this._isDownSelection=0;
- var n = this.getPreviousItem(this.selectedItems[this.selectedItems.length-1], 1);
- if (n)
- this.timedSelect(n, this._selectDelay);
- ]]>
- </body>
- </method>
-
- <method name="navigateToNextItem">
- <parameter name="event"/>
- <body>
- <![CDATA[
- if (event.target != this)
- return;
- var n;
- if (this.selectedItems.length == 0) {
- n = this.getItemAtIndex(0);
- }
- else
- {
- this._isUpSelection=0;
- this._isDownSelection=0;
- n = this.getNextItem(this.selectedItems[this.selectedItems.length-1], 1);
- }
-
- if (n)
- this.timedSelect(n, this._selectDelay);
- ]]>
- </body>
- </method>
-
- <method name="navigateAndSelectNextItem">
- <parameter name="event"/>
- <body>
- <![CDATA[
- var l=this.selectedItems.length;
- if (event.target != this || l < 1 || this.selType != "multiple")
- return;
- var n = this.getNextItem(this.selectedItems[l-1], 1);
- if (n)
- {
- if ( this._isUpSelection)
- {
- if ( l > 1 )
- this.removeItemFromSelection(this.selectedItems[l-1]);
- if ( l <= 2 )
- this._isUpSelection=0;
- }
- else
- {
- this.addItemToSelection(n);
- this._isDownSelection=1;
- }
- }
- ]]>
- </body>
- </method>
- <method name="navigateAndSelectPreviousItem">
- <parameter name="event"/>
- <body>
- <![CDATA[
- var l = this.selectedItems.length;
- if (event.target != this || l < 1 || this.selType != "multiple")
- return;
- var n = this.getPreviousItem(this.selectedItems[l-1], 1);
- if (n)
- {
- if ( this._isDownSelection)
- {
- if ( l > 1 )
- this.removeItemFromSelection(this.selectedItems[l-1]);
- if ( l <= 2 )
- this._isDownSelection=0;
- } else
- {
- this.addItemToSelection(n);
- this._isUpSelection=1;
- }
- }
- ]]>
- </body>
- </method>
- </implementation>
-
- <handlers>
-
- <handler event="keypress" modifiers="shift" keycode="vk_down">
- <![CDATA[
- this.navigateAndSelectNextItem(event);
- ]]>
- </handler>
-
- <handler event="keypress" modifiers="shift" keycode="vk_right">
- <![CDATA[
- this.navigateAndSelectNextItem(event);
- ]]>
- </handler>
- <handler event="keypress" modifiers="shift" keycode="vk_up">
- <![CDATA[
- this.navigateAndSelectPreviousItem(event);
- ]]>
- </handler>
-
- <handler event="keypress" modifiers="shift" keycode="vk_left">
- <![CDATA[
- this.navigateAndSelectPreviousItem(event);
- ]]>
- </handler>
-
- <handler event="keypress" keycode="vk_up">
- <![CDATA[
- this.navigateToPreviousItem(event);
- ]]>
- </handler>
- <handler event="keypress" keycode="vk_left">
- <![CDATA[
- if (event.target != this)
- return;
- this.navigateToPreviousItem(event);
- ]]>
- </handler>
- <handler event="keypress" keycode="vk_down">
- <![CDATA[
- this.navigateToNextItem(event);
- ]]>
- </handler>
- <handler event="keypress" keycode="vk_right">
- <![CDATA[
- this.navigateToNextItem(event);
- ]]>
- </handler>
- <handler event="mousedown">
- <![CDATA[
- var targetItem = event.target;
- if (targetItem.localName == "descriptionitem" && !event.ctrlKey && !event.shiftKey && !event.metaKey)
- {
- if (!targetItem.hasAttribute('selected'))
- this.selectItem(targetItem);
- this.currentItem = targetItem;
- }
- if (document.commandDispatcher.focusedElement != this)
- this.focus(); // make sure the description has focus...
- ]]>
- </handler>
- <handler event="click">
- <![CDATA[
- if (event.button != 0) return;
-
- var targetItem = event.target;
- if (targetItem.localName == "descriptionitem")
- {
- if (this.selType != "multiple")
- this.selectItem(targetItem);
- else if (event.ctrlKey || event.metaKey) {
- this.toggleItemSelection(targetItem);
- this.currentItem = targetItem;
- }
- else if (event.shiftKey) {
- this.selectItemRange(null, targetItem);
- this.currentItem = targetItem;
- }
- else {
- /* We want to deselect all the selected items except what was
- clicked, UNLESS it was a right-click. We have to do this
- in click rather than mousedown so that you can drag a
- selected group of items */
-
- var selectedItems = this.selectedItems;
- var didSuppressSelect = false;
- var i = 0;
- while (i < selectedItems.length)
- {
- if (selectedItems[i] != targetItem)
- {
- if (!didSuppressSelect)
- {
- this._suppressOnSelect = true;
- didSuppressSelect = true;
- }
- this.removeItemFromSelection(selectedItems[i]);
- }
- else
- i++;
- }
- if (didSuppressSelect)
- this._suppressOnSelect = false;
- }
- }
- else
- {
- if (this.selType != "multiple" || (!event.ctrlKey && !event.shiftKey && !event.metaKey))
- this.clearSelection();
- }
- ]]>
- </handler>
- </handlers>
- </binding>
-
- <binding id="descriptionitem">
- <content>
- <xul:hbox class="attachmentBox" xbl:inherits="orient" align="start">
- <xul:label class="descriptioncell-label" xbl:inherits="value=label,flex=flexlabel,crop,disabled,context" flex="1" dir="ltr" crop="center"/>
- </xul:hbox>
- </content>
- </binding>
-
- <binding id="descriptionitem-iconic">
- <content>
- <xul:hbox class="attachmentBox" xbl:inherits="orient" align="center">
- <xul:image class="descriptioncell-icon" xbl:inherits="src=image"/>
- <xul:label class="descriptioncell-label" xbl:inherits="value=label,flex=flexlabel,crop,disabled,context" flex="1" dir="ltr" crop="center"/>
- </xul:hbox>
- </content>
- </binding>
-
- <!-- Message Pane Widgets -->
-
- <!-- mail-toggle-headerfield: non email addrss headers which have a toggle associated with them (i.e. the subject).
- use label to set the header name.
- use headerValue to set the header value. -->
- <binding id="mail-toggle-headerfield">
- <content>
- <xul:hbox class="headerNameBox" align="start">
- <xul:image class="expandHeaderViewButton" xbl:inherits="onclick=ontwistyclick"/>
- <xul:spacer flex="1"/>
- <xul:label class="headerName" xbl:inherits="value=label"/>
- </xul:hbox>
- <xul:textbox originalclass="headerValue plain" appendoriginalclass="true" keywordrelated="true" class="headerValue plain" anonid="headerValue" flex="1" readonly="true"/>
- </content>
-
- <implementation>
- <property name="headerValue" onset="return document.getAnonymousElementByAttribute(this, 'anonid', 'headerValue').value = val;"/>
- </implementation>
- </binding>
-
- <!-- mail-headerfield: presents standard text header name & value pairs. Don't use this for email addresses.
- use label to set the header name.
- use headerValue to set the header value. -->
- <binding id="mail-headerfield">
- <content>
- <xul:hbox class="headerNameBox" align="start">
- <xul:label class="headerName" xbl:inherits="value=label" flex="1"/>
- </xul:hbox>
- <xul:textbox originalclass="headerValue plain" appendoriginalclass="true" keywordrelated="true" class="headerValue plain" anonid="headerValue" flex="1" readonly="true"/>
- </content>
-
- <implementation>
- <property name="headerValue" onset="return document.getAnonymousElementByAttribute(this, 'anonid', 'headerValue').value = val;"/>
- </implementation>
- </binding>
-
- <binding id="mail-urlfield" extends="chrome://messenger/content/mailWidgets.xml#mail-headerfield">
- <content>
- <xul:hbox class="headerNameBox" align="start">
- <xul:label class="headerName" xbl:inherits="value=label" flex="1"/>
- </xul:hbox>
- <xul:label originalclass="headerValue plain headerValueUrl" onclick="if (!event.button) messenger.launchExternalURL(event.target.value);"
- appendoriginalclass="true" keywordrelated="true" class="headerValue plain headerValueUrl"
- anonid="headerValue" flex="1" readonly="true" context="copyUrlPopup"/>
- </content>
- </binding>
-
- <binding id="mail-emailheaderfield">
- <content>
- <xul:hbox class="headerNameBox" align="start">
- <xul:label class="headerName" xbl:inherits="value=label" flex="1"/>
- </xul:hbox>
- <xul:mail-emailaddress anonid="emailAddressNode"/>
- </content>
-
- <implementation>
- <property name="emailAddressNode" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'emailAddressNode');"
- readonly="true"/>
- </implementation>
- </binding>
-
- <!-- multi-emailHeaderField: presents multiple emailheaderfields with a toggle -->
- <binding id="mail-multi-emailHeaderField">
- <content>
- <xul:hbox class="headerNameBox" align="start" pack="end">
- <xul:image class="addresstwisty" anonid="toggleIcon"
- onclick="toggleAddressView();"/>
- <xul:label class="headerName" xbl:inherits="value=label"/>
- </xul:hbox>
-
- <xul:label class="headerValue" anonid="emailAddresses" flex="1"/>
- <xul:label class="headerValue" anonid="longEmailAddresses" flex="1" collapsed="true"/>
- </content>
-
- <implementation>
- <constructor>
- <![CDATA[
- this.mLongViewCreated = false;
- this.mAddresses = new Array;
- ]]>
- </constructor>
-
- <field name="mLongViewCreated"/>
- <field name="mAddresses"/>
- <!-- as a perf optimization we are going to keep a cache of email address nodes which we've
- created around for the lifetime of the widget. mSizeOfAddressCache controls how many of these
- elements we keep around -->
- <field name="mSizeOfAddressCache">3</field>
-
- <!-- addAddressView: a public method used to add an address to this widget.
- aAddresses is an object with 3 properties: displayName, emailAddress and fullAddress
- -->
- <method name="addAddressView">
- <parameter name="aAddress"/>
- <body>
- <![CDATA[
- this.mAddresses.push(aAddress);
- ]]>
- </body>
- </method>
-
- <!-- updateEmailAddressNode: private method used to set properties on an address node -->
- <method name="updateEmailAddressNode">
- <parameter name="aEmailNode"/>
- <parameter name="aAddress"/>
- <body>
- <![CDATA[
- aEmailNode.setAttribute("label", aAddress.fullAddress);
- aEmailNode.setTextAttribute("emailAddress", aAddress.emailAddress);
- aEmailNode.setTextAttribute("fullAddress", aAddress.fullAddress);
- aEmailNode.setTextAttribute("displayName", aAddress.displayName);
-
- try
- {
- if ("AddExtraAddressProcessing" in top)
- AddExtraAddressProcessing(aAddress.emailAddress, aEmailNode);
- }
- catch(ex)
- {
- dump("AddExtraAddressProcessing failed: " + ex);
- }
- ]]>
- </body>
- </method>
-
- <!-- fillCachedAddresses: private method used to fill up any cached pre-existing
- emailAddress fields without creating new email address fields. Returns a remainder
- for the # of addresses which require new addresses being created.
- Invariants: 1) aNumAddressesToShow >= 0 && it is <= mAddresses.length -->
- <method name="fillCachedAddresses">
- <parameter name="aAddressesNode"/>
- <parameter name="aNumAddressesToShow"/>
- <body>
- <![CDATA[
- var numExistingCachedAddresses = aAddressesNode.childNodes.length;
- if (!numExistingCachedAddresses)
- return this.mAddresses.length; // we couldn't pre fill anything
- else if (numExistingCachedAddresses > 1)
- numExistingCachedAddresses = (numExistingCachedAddresses + 1)/ 2;
-
- var index = 0;
- var numAddressesAdded = 0;
- var emailAddressNode;
- var commaNode;
- while (numAddressesAdded < numExistingCachedAddresses && numAddressesAdded < aNumAddressesToShow)
- {
- if (index && numExistingCachedAddresses > 1)
- {
- commaNode = aAddressesNode.childNodes[index++];
- if (commaNode)
- commaNode.removeAttribute('collapsed');
- }
-
- // get the node pointed to by index
- emailAddressNode = aAddressesNode.childNodes[index++];
- this.updateEmailAddressNode(emailAddressNode, this.mAddresses[numAddressesAdded]);
- emailAddressNode.removeAttribute('collapsed');
- numAddressesAdded++;
- }
-
- // if we have added all of our elements but we still have more cached items in this address node
- // then make sure the extra cached copies are collapsed...
- numExistingCachedAddresses = aAddressesNode.childNodes.length; // reset
- while (index < numExistingCachedAddresses)
- {
- aAddressesNode.childNodes[index++].setAttribute('collapsed', true);
- }
-
- return this.mAddresses.length - numAddressesAdded;
- ]]>
- </body>
- </method>
-
- <!-- fillAddressesNode: private method used to create email address nodes for either our short
- or long view. aAddressesNode: the div we want to add addresses too.
- aNumAddressesToShow: number of addresses to put into the list -->
- <method name="fillAddressesNode">
- <parameter name="aAddressesNode"/>
- <parameter name="aNumAddressesToShow"/>
- <body>
- <![CDATA[
- var numAddresses = this.mAddresses.length;
- if (aNumAddressesToShow <= 0 || aNumAddressesToShow > numAddresses) // then show all
- aNumAddressesToShow = numAddresses;
-
- // before we try to create email address nodes, try to leverage any cached nodes...
- var remainder = this.fillCachedAddresses(aAddressesNode, aNumAddressesToShow);
- var index = numAddresses - remainder;
- while (index < numAddresses && index < aNumAddressesToShow)
- {
- var newAddressNode = document.createElement("mail-emailaddress");
- if (index)
- {
- var textNode = document.createElement("text");
- textNode.setAttribute("value", ", ");
- textNode.setAttribute("class", "emailSeparator");
- aAddressesNode.appendChild(textNode);
- }
-
- var itemInDocument = aAddressesNode.appendChild(newAddressNode);
- this.updateEmailAddressNode(itemInDocument, this.mAddresses[index]);
- index++;
- }
- ]]>
- </body>
- </method>
-
- <property name="emailAddresses" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'emailAddresses');"
- readonly="true"/>
- <property name="longEmailAddresses" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'longEmailAddresses');"
- readonly="true"/>
- <property name="toggleIcon" onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'toggleIcon');"
- readonly="true"/>
-
- <!-- buildView: public method used by callers when they are done adding all the email addresses to the widget
- aNumAddressesToShow: total # of addresses to show in the short view -->
- <method name="buildViews">
- <parameter name="aNumAddressesToShow"/>
- <body>
- <![CDATA[
- // always build the short view...its cheap...
- this.fillAddressesNode(this.emailAddresses, aNumAddressesToShow);
- // if we are currently toggled to show all the email addresses, build the long one too...
- if (this.emailAddresses.collapsed)
- this.buildLongView();
-
- // make sure the icon is always visible if we have more than the # of addresses to show
- this.toggleIcon.collapsed = this.mAddresses.length <= aNumAddressesToShow;
- ]]>
- </body>
- </method>
-
- <!-- buildLongView: private method used for delayed construction of the long view -->
- <method name="buildLongView">
- <body>
- <![CDATA[
- if (!this.mLongViewCreated)
- {
- this.fillAddressesNode(this.longEmailAddresses, -1);
- this.mLongViewCreated = true;
- }
- ]]>
- </body>
- </method>
-
- <method name="toggleAddressView">
- <body>
- <![CDATA[
- var shortNode = this.emailAddresses;
- var longNode = this.longEmailAddresses;
- var imageNode = this.toggleIcon;
- // test to see which if short is already collapsed...
- if (shortNode.collapsed)
- {
- longNode.collapsed = true;
- shortNode.collapsed = false;
- imageNode.removeAttribute("open");
- }
- else
- {
- this.buildLongView();
- shortNode.collapsed = true;
- longNode.collapsed = false;
- imageNode.setAttribute("open", "true");
-
- if (!this.mLongViewCreated)
- {
- // Need to call UpdateMessageHeaders() because this is the first
- // time the long view is being built. This is required in order
- // to update the addresses of the long view that might contain
- // extra image info.
- // It should also only be called from toggleAddressView(), not
- // from buildView().
- UpdateMessageHeaders();
- }
- }
- ]]>
- </body>
- </method>
-
- <!-- internal method used to clear both our divs -->
- <method name="clearChildNodes">
- <parameter name="aParentNode"/>
- <body>
- <![CDATA[
- // we want to keep around the first mSizeOfAddressCache email address nodes
- // don't forget that we have comma text nodes in there too so really we want to keep
- // around cache size * 2 - 1.
- var numItemsToPreserve = this.mSizeOfAddressCache * 2 - 1;
- var numItemsInNode = aParentNode.childNodes.length;
-
- while (numItemsInNode && (numItemsInNode > numItemsToPreserve))
- {
- aParentNode.removeChild(aParentNode.childNodes[numItemsInNode-1]);
- numItemsInNode = numItemsInNode - 1;
- }
- ]]>
- </body>
- </method>
-
- <method name="clearEmailAddresses">
- <body>
- <![CDATA[
- // clear out our local state
- this.mAddresses = new Array;
- this.mLongViewCreated = false;
-
- // remove anything inside of each of our labels....
- var parentLabel = this.emailAddresses;
- if (parentLabel)
- this.clearChildNodes(parentLabel);
- parentLabel = this.longEmailAddresses;
- if (parentLabel)
- this.clearChildNodes(parentLabel);
- ]]>
- </body>
- </method>
- </implementation>
- </binding>
-
- <binding id="mail-emailaddress">
- <content popup="emailAddressPopup" context="emailAddressPopup">
- <xul:label anonid="emailValue" class="emailDisplayButton plain"
- xbl:inherits="value=label,crop"/>
- <xul:image class="emailDisplayImage" anonid="emailImage"
- xbl:inherits="src=image"/>
- </content>
-
- <implementation>
- <property name="label" onset="this.getPart('emailValue').setAttribute('label',val); return val;"
- onget="return this.getPart('emailValue').getAttribute('label');"/>
- <property name="crop" onset="this.getPart('emailValue').setAttribute('crop',val); return val;"
- onget="return this.getPart('emailValue').getAttribute('crop');"/>
- <property name="disabled" onset="this.getPart('emailValue').setAttribute('disabled',val); return val;"
- onget="return this.getPart('emailValue').getAttribute('disabled');"/>
- <property name="src" onset="this.getPart('emailImage').setAttribute('src',val); return val;"
- onget="return this.getPart('emailImage').getAttribute('src');"/>
- <property name="imgalign" onset="this.getPart('emailImage').setAttribute('imgalign',val); return val;"
- onget="return this.getPart('emailImage').getAttribute('imgalign');"/>
-
- <method name="getPart">
- <parameter name="aPartId"/>
- <body><![CDATA[
- return document.getAnonymousElementByAttribute(this, "anonid", aPartId);
- ]]></body>
- </method>
-
- <method name="setTextAttribute">
- <parameter name="attributeName"/>
- <parameter name="attributeValue"/>
- <body><![CDATA[
- this.setAttribute(attributeName, attributeValue);
- this.getPart("emailImage").setAttribute(attributeName, attributeValue);
- this.getPart("emailValue").setAttribute(attributeName, attributeValue);
- ]]></body>
- </method>
-
- <method name="getTextAttribute">
- <parameter name="attributeName"/>
- <body><![CDATA[
- return this.getPart("emailValue").getAttribute(attributeName);
- ]]></body>
- </method>
-
- <method name="GetIconNode">
- <body><![CDATA[
- return this.getPart("emailImage");
- ]]></body>
- </method>
- </implementation>
- </binding>
-
- <binding id="search-menulist-abstract" name="searchMenulistAbstract" extends="xul:box">
- <content>
- <xul:menulist class="search-menulist" xbl:inherits="flex" oncommand="this.parentNode.onSelect(event)">
- <xul:menupopup class="search-menulist-popup"/>
- </xul:menulist>
- </content>
-
- <implementation>
- <field name="internalScope">null</field>
- <field readonly="true" name="validityManager">
- <![CDATA[
- Components.classes['@mozilla.org/mail/search/validityManager;1'].getService(Components.interfaces.nsIMsgSearchValidityManager);
- ]]>
- </field>
- <property name="searchScope" onget="return this.internalScope;">
- <!-- scope ID - retrieve the table -->
- <setter>
- <![CDATA[
- // if scope isn't changing this is a noop
- if (this.internalScope == val) return val;
-
- this.internalScope = val;
- this.refreshList();
- var targets = this.targets;
- if (targets) {
- for (var i=0; i< targets.length; i++) {
- targets[i].searchScope = val;
- }
- }
- return val;
- ]]>
- </setter>
- </property>
-
- <property name="validityTable" readonly="true" onget="return this.validityManager.getTable(this.searchScope)"/>
-
- <property name="valueStrings" readonly="true">
- <getter>
- <![CDATA[
- var strings = new Array;
- var ids = this.valueIds;
- var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- var hdrsArray = null;
- try
- {
- var hdrs = pref.getCharPref("mailnews.customHeaders");
- hdrs = hdrs.replace(/\s+/g,''); //remove white spaces before splitting
- hdrsArray = hdrs.match(/[^:]+/g);
- }
- catch(ex)
- {
- }
- var bundle = this.stringBundle;
- var j=0;
- for (var i=0; i<ids.length; i++)
- {
- if(ids[i] > Components.interfaces.nsMsgSearchAttrib.OtherHeader && hdrsArray)
- strings[i] = hdrsArray[j++];
- else
- strings[i] = this.stringBundle.GetStringFromID(ids[i]);
- }
- return strings;
- ]]>
- </getter>
- </property>
- <property name="targets" readonly="true">
- <getter>
- <![CDATA[
- var forAttrs = this.getAttribute("for");
- if (!forAttrs) return null;
- var targetIds = forAttrs.split(",");
- if (targetIds.length == 0) return null;
-
- var targets = new Array;
- var j=0;
- for (var i=0; i<targetIds.length;i++) {
- var target = document.getElementById(targetIds[i]);
- if (target) targets[j++] = target;
- }
- return targets;
- ]]>
- </getter>
- </property>
-
- <property name="optargets" readonly="true">
- <getter>
- <![CDATA[
- var forAttrs = this.getAttribute("opfor");
- if (!forAttrs) return null;
- var optargetIds = forAttrs.split(",");
- if (optargetIds.length == 0) return null;
-
- var optargets = new Array;
- var j=0;
- for (var i=0; i<optargetIds.length;i++) {
- var optarget = document.getElementById(optargetIds[i]);
- if (optarget) optargets[j++] = optarget;
- }
- return optargets;
- ]]>
- </getter>
- </property>
-
- <!-- value forwards to the internal menulist's "value" attribute -->
- <property name="value" onget="return document.getAnonymousNodes(this)[0].selectedItem.getAttribute('value');">
- <setter>
- <![CDATA[
- var menulist = document.getAnonymousNodes(this)[0];
- var dataItems = menulist.getElementsByAttribute("value", val);
- if (dataItems.item(0))
- menulist.selectedItem = dataItems[0];
-
- // now notify targets of new parent's value
- var targets = this.targets;
- if (targets) {
- for (var i=0; i < targets.length; i++) {
- targets[i].parentValue = val;
- }
- }
-
- // now notify optargets of new op parent's value
- var optargets = this.optargets;
- if (optargets) {
- for (i=0; i < optargets.length; i++) {
- optargets[i].opParentValue = val;
- }
- }
-
- return val;
- ]]>
- </setter>
- </property>
- <!-- label forwards to the internal menulist's "label" attribute -->
- <property name="label" onget="return document.getAnonymousNodes(this)[0].selectedItem.getAttribute('label');">
- </property>
- <method name="refreshList">
- <body>
- <![CDATA[
- var menuItemIds = this.valueIds;
- var menuItemStrings = this.valueStrings;
-
- var menulist = document.getAnonymousNodes(this)[0];
- var popup = menulist.firstChild;
-
- // save our old "value" so we can restore it later
- var oldData = menulist.value;
-
- // remove the old popup children
- while (popup.hasChildNodes())
- popup.removeChild(popup.lastChild);
-
- var newSelection;
- var customizePos=-1;
- for (var i=0; i<menuItemIds.length; i++)
- {
- // create the menuitem
- if (Components.interfaces.nsMsgSearchAttrib.OtherHeader == menuItemIds[i].toString())
- customizePos = i;
- else
- {
- var menuitem = document.createElement("menuitem");
- menuitem.setAttribute("label", menuItemStrings[i]);
- menuitem.setAttribute("value", menuItemIds[i]);
- popup.appendChild(menuitem);
- // try to restore the selection
- if (!newSelection || oldData == menuItemIds[i].toString())
- newSelection = menuitem;
- }
- }
- if (customizePos != -1)
- {
- var separator = document.createElement("menuseparator");
- popup.appendChild(separator);
- menuitem = document.createElement("menuitem");
- menuitem.setAttribute("label", menuItemStrings[customizePos]);
- menuitem.setAttribute("value", menuItemIds[customizePos]);
- popup.appendChild(menuitem);
- }
- // now restore the selection
- menulist.selectedItem = newSelection;
-
- ]]>
- </body>
- </method>
- <method name="onSelect">
- <parameter name="event"/>
- <body>
- <![CDATA[
- var menulist = document.getAnonymousNodes(this)[0];
- // notify targets
- var targets = this.targets;
- if (targets) {
- for (var i=0; i < targets.length; i++) {
- targets[i].parentValue = menulist.value;
- }
- }
-
- var optargets = this.optargets;
- if (optargets) {
- for (i=0; i < optargets.length; i++) {
- optargets[i].opParentValue = menulist.value;
- }
- }
- ]]>
- </body>
- </method>
- </implementation>
- </binding>
-
- <!-- searchattribute - Subject, Sender, To, CC, etc. -->
- <binding id="searchattribute" name="searchAttribute"
- extends="chrome://messenger/content/mailWidgets.xml#search-menulist-abstract">
- <implementation>
- <field name="stringBundle">
- <![CDATA[
- srGetStrBundle("chrome://messenger/locale/search-attributes.properties");
- ]]>
- </field>
- <property name="valueIds" readonly="true">
- <getter>
- <![CDATA[
- var length = new Object;
- return this.validityTable.getAvailableAttributes(length);
- ]]>
- </getter>
- </property>
- <constructor>
- <![CDATA[
- initializeTermFromId(this.id);
- ]]>
- </constructor>
- </implementation>
- </binding>
-
- <!-- searchoperator - Contains, Is Less than, etc -->
- <binding id="searchoperator" name="searchOperator"
- extends="chrome://messenger/content/mailWidgets.xml#search-menulist-abstract">
- <implementation>
- <field name="searchAttribute">Components.interfaces.nsMsgSearchAttrib.Default</field>
- <field name="stringBundle">
- <![CDATA[
- srGetStrBundle("chrome://messenger/locale/search-operators.properties");
- ]]>
- </field>
- <property name="valueIds" readonly="true">
- <getter>
- <![CDATA[
- var length = new Object;
- return this.validityTable.getAvailableOperators(this.searchAttribute,length);
- ]]>
- </getter>
- </property>
- <property name="parentValue">
- <setter>
- <![CDATA[
- if (this.searchAttribute == val && val != Components.interfaces.nsMsgSearchAttrib.OtherHeader) return val;
- this.searchAttribute = val;
- this.refreshList();
- if (val == Components.interfaces.nsMsgSearchAttrib.OtherHeader)
- {
- window.openDialog('chrome://messenger/content/CustomHeaders.xul', "", 'modal,centerscreen,resizable,titlebar,chrome', null);
- setTimeout(UpdateAfterCustomHeaderChange, 0); // XXX bug 212625
- }
- return val;
- ]]>
- </setter>
- <getter>
- <![CDATA[
- return this.searchAttribute;
- ]]>
- </getter>
- </property>
- </implementation>
- </binding>
-
- <!-- searchvalue - a widget which dynamically changes its user interface
- depending on what type of data it's supposed to be showing
- currently handles arbitrary text entry, and menulists for
- priority, status, junk status, hasAttachment status, and addressbook
- -->
- <binding id="searchvalue" name="searchValue">
- <content>
- <xul:textbox flex="1" class="search-value-textbox"/>
- <xul:menulist flex="1" class="search-value-menulist">
- <xul:menupopup class="search-value-popup">
- <xul:menuitem value="2" stringTag="priorityLowest" class="search-value-menuitem"/>
- <xul:menuitem value="3" stringTag="priorityLow" class="search-value-menuitem"/>
- <xul:menuitem value="4" stringTag="priorityNormal" class="search-value-menuitem"/>
- <xul:menuitem value="5" stringTag="priorityHigh" class="search-value-menuitem"/>
- <xul:menuitem value="6" stringTag="priorityHighest" class="search-value-menuitem"/>
- </xul:menupopup>
- </xul:menulist>
- <xul:menulist flex="1" class="search-value-menulist">
- <xul:menupopup class="search-value-popup">
- <xul:menuitem value="2" stringTag="replied" class="search-value-menuitem"/>
- <xul:menuitem value="1" stringTag="read" class="search-value-menuitem"/>
- <xul:menuitem value="65536" stringTag="new" class="search-value-menuitem"/>
- <xul:menuitem value="4096" stringTag="forwarded" class="search-value-menuitem"/>
- <xul:menuitem value="4" stringTag="flagged" class="search-value-menuitem"/>
- </xul:menupopup>
- </xul:menulist>
- <xul:textbox flex="1" class="search-value-textbox"/>
- <xul:menulist flex="1" class="search-value-menulist">
- <xul:menupopup class="search-value-popup" ref="moz-abdirectory://"
- datasources="rdf:addressdirectory"
- sortActive="true"
- sortDirection="ascending"
- sortResource="http://home.netscape.com/NC-rdf#DirTreeNameSort">
- <xul:template>
- <xul:rule nc:IsRemote="true"/>
- <xul:rule nc:IsMailList="false">
- <xul:menuitem uri="..."
- label="rdf:http://home.netscape.com/NC-rdf#DirName"
- value="rdf:http://home.netscape.com/NC-rdf#DirUri"/>
- </xul:rule>
- </xul:template>
- </xul:menupopup>
- </xul:menulist>
- <xul:menulist flex="1" class="search-value-menulist">
- <xul:menupopup class="search-value-popup">
- <xul:menuitem value="0" class="search-value-menuitem"/>
- <xul:menuitem value="1" class="search-value-menuitem"/>
- <xul:menuitem value="2" class="search-value-menuitem"/>
- <xul:menuitem value="3" class="search-value-menuitem"/>
- <xul:menuitem value="4" class="search-value-menuitem"/>
- <xul:menuitem value="5" class="search-value-menuitem"/>
- </xul:menupopup>
- </xul:menulist>
- <xul:menulist flex="1" class="search-value-menulist">
- <xul:menupopup class="search-value-popup">
- <xul:menuitem value="2" stringTag="junk" class="search-value-menuitem"/>
- </xul:menupopup>
- </xul:menulist>
- <xul:menulist flex="1" class="search-value-menulist">
- <xul:menupopup class="search-value-popup">
- <xul:menuitem value="0" stringTag="hasAttachments" class="search-value-menuitem"/>
- </xul:menupopup>
- </xul:menulist>
- </content>
- <implementation>
- <field name="internalOperator">null</field>
- <field name="internalAttribute">null</field>
- <field name="internalValue">null</field>
-
- <property name="opParentValue" onget="return this.internalOperator;">
- <setter>
- <![CDATA[
- // noop if we're not changing it
- if (this.internalOperator == val) return val;
-
- // if it's not sender, we don't care
- if (this.searchAttribute != Components.interfaces.nsMsgSearchAttrib.Sender) {
- this.internalOperator = val;
- return val;
- }
-
- var children = document.getAnonymousNodes(this);
- if (val == Components.interfaces.nsMsgSearchOp.IsntInAB ||
- val == Components.interfaces.nsMsgSearchOp.IsInAB) {
- // if the old internalOperator was
- // IsntInAB or IsInAB, and the new internalOperator is
- // IsntInAB or IsInAB, noop because the search value
- // was an ab type, and it still is.
- // otherwise, switch to the ab picker and select the PAB
- if (this.internalOperator != Components.interfaces.nsMsgSearchOp.IsntInAB &&
- this.internalOperator != Components.interfaces.nsMsgSearchOp.IsInAB) {
- var abs = children[4].getElementsByAttribute("value", "moz-abmdbdirectory://abook.mab");
- if (abs.item(0))
- children[4].selectedItem = abs[0];
- this.setAttribute("selectedIndex", "4");
- }
- }
- else {
- // if the old internalOperator wasn't
- // IsntInAB or IsInAB, and the new internalOperator isn't
- // IsntInAB or IsInAB, noop because the search value
- // wasn't an ab type, and it still isn't.
- // otherwise, switch to the textbox and clear it
- if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
- this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB) {
- children[0].value = "";
- this.setAttribute("selectedIndex", "0");
- }
- }
-
- this.internalOperator = val;
- return val;
- ]]>
- </setter>
- </property>
- <!-- parentValue forwards to the attribute -->
- <property name="parentValue" onset="return this.searchAttribute=val;"
- onget="return this.searchAttribute;"/>
- <property name="searchAttribute" onget="return this.internalAttribute;">
- <setter>
- <![CDATA[
- // noop if we're not changing it
- if (this.internalAttribute == val) return val;
- this.internalAttribute = val;
-
- // if the searchAttribute changing, null out the internalOperator
- this.internalOperator = null;
-
- // we inherit from a deck, so just use it's index attribute
- // to hide/show widgets
- if (val == Components.interfaces.nsMsgSearchAttrib.Priority)
- this.setAttribute("selectedIndex", "1");
- else if (val == Components.interfaces.nsMsgSearchAttrib.MsgStatus)
- this.setAttribute("selectedIndex", "2");
- else if (val == Components.interfaces.nsMsgSearchAttrib.Date)
- this.setAttribute("selectedIndex", "3");
- else if (val == Components.interfaces.nsMsgSearchAttrib.Sender) {
- // since the internalOperator is null
- // this is the same as the initial state
- // the initial state for Sender isn't an ab type search
- // it's a text search, so show the textbox
- this.setAttribute("selectedIndex", "0");
- }
- else if (val == Components.interfaces.nsMsgSearchAttrib.Label)
- {
- var children = document.getAnonymousNodes(this);
- var abs = children[5].getElementsByAttribute("value", "1");
- if (abs.item(0))
- children[5].selectedItem = abs[0];
- this.setAttribute("selectedIndex", "5");
- }
- else if (val == Components.interfaces.nsMsgSearchAttrib.JunkStatus) {
- this.setAttribute("selectedIndex", "6");
- }
- else if (val == Components.interfaces.nsMsgSearchAttrib.HasAttachmentStatus) {
- this.setAttribute("selectedIndex", "7");
- }
- else {
- // a normal text field
- this.setAttribute("selectedIndex", "0");
- }
- return val;
- ]]>
- </setter>
- </property>
- <property name="value" onget="return this.internalValue;">
- <setter>
- <![CDATA[
- // val is a nsIMsgSearchValue object
- this.internalValue = val;
- var attrib = val.attrib;
- var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
- var children = document.getAnonymousNodes(this);
- this.searchAttribute = attrib;
- if (attrib == nsMsgSearchAttrib.Priority) {
- var matchingPriority =
- children[1].getElementsByAttribute("value", val.priority);
- if (matchingPriority.item(0))
- children[1].selectedItem = matchingPriority[0];
- }
- else if (attrib == nsMsgSearchAttrib.MsgStatus) {
- var matchingStatus =
- children[2].getElementsByAttribute("value", val.status);
- if (matchingStatus.item(0))
- children[2].selectedItem = matchingStatus[0];
- }
- else if (attrib == nsMsgSearchAttrib.AgeInDays)
- children[0].value = val.age;
- else if (attrib == nsMsgSearchAttrib.Date)
- children[3].value = convertPRTimeToString(val.date);
- else if (attrib == nsMsgSearchAttrib.Sender)
- {
- if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
- this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB) {
- var abs = children[4].getElementsByAttribute("value", val.str);
- if (abs.item(0))
- children[4].selectedItem = abs[0];
- }
- else
- children[0].value = val.str;
- }
- else if (attrib == nsMsgSearchAttrib.Label)
- {
- var labelVal = children[5].getElementsByAttribute("value", val.label);
- if (labelVal.item(0))
- children[5].selectedItem = labelVal[0];
- }
- else if (attrib == nsMsgSearchAttrib.JunkStatus) {
- var junkStatus =
- children[6].getElementsByAttribute("value", val.junkStatus);
- if (junkStatus.item(0))
- children[6].selectedItem = junkStatus[0];
- }
- else if (attrib == nsMsgSearchAttrib.HasAttachmentStatus) {
- var hasAttachmentStatus =
- children[7].getElementsByAttribute("value", val.hasAttachmentStatus);
- if (hasAttachmentStatus.item(0))
- children[7].selectedItem = hasAttachmentStatus[0];
- }
- else if (attrib == nsMsgSearchAttrib.Size) {
- children[0].value = val.size;
- }
- else
- children[0].value = val.str;
- return val;
- ]]>
- </setter>
- </property>
- <method name="save">
- <body>
- <![CDATA[
- var searchValue = this.value;
- var searchAttribute = this.searchAttribute;
- var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
- var children = document.getAnonymousNodes(this);
-
- searchValue.attrib = searchAttribute;
- if (searchAttribute == nsMsgSearchAttrib.Priority) {
- searchValue.priority = children[1].selectedItem.value;
- }
- else if (searchAttribute == nsMsgSearchAttrib.MsgStatus)
- searchValue.status = children[2].value;
- else if (searchAttribute == nsMsgSearchAttrib.AgeInDays)
- searchValue.age = children[0].value;
- else if (searchAttribute == nsMsgSearchAttrib.Date)
- searchValue.date = convertStringToPRTime(children[3].value);
- else if (searchAttribute == nsMsgSearchAttrib.Sender) {
- if (this.internalOperator == Components.interfaces.nsMsgSearchOp.IsntInAB ||
- this.internalOperator == Components.interfaces.nsMsgSearchOp.IsInAB)
- searchValue.str = children[4].selectedItem.value;
- else
- searchValue.str = children[0].value;
- }
- else if (searchAttribute == nsMsgSearchAttrib.Label)
- searchValue.label = children[5].selectedItem.value;
- else if (searchAttribute == nsMsgSearchAttrib.JunkStatus)
- searchValue.junkStatus = children[6].value;
- else if (searchAttribute == nsMsgSearchAttrib.Size)
- searchValue.size = children[0].value;
- else if (searchAttribute == nsMsgSearchAttrib.HasAttachmentStatus)
- searchValue.status = 0x10000000; // 0x10000000 is MSG_FLAG_ATTACHMENT;
- else
- searchValue.str = children[0].value;
- ]]>
- </body>
- </method>
- <method name="saveTo">
- <parameter name="searchValue"/>
- <body>
- <![CDATA[
- this.internalValue = searchValue;
- this.save();
- ]]>
- </body>
- </method>
- <method name="fillStringsForChildren">
- <parameter name="parentNode"/>
- <parameter name="bundle"/>
- <body>
- <![CDATA[
- var children = parentNode.childNodes;
- var len=children.length;
- for (var i=0; i<len; i++) {
- var node = children[i];
- var stringTag = node.getAttribute("stringTag");
- if (stringTag) {
- var attr = (node.tagName == "label") ? "value" : "label";
- node.setAttribute(attr, bundle.GetStringFromName(stringTag));
- }
- }
- ]]>
- </body>
- </method>
- <method name="initialize">
- <parameter name="menulist"/>
- <parameter name="bundle"/>
- <body>
- <![CDATA[
- this.fillStringsForChildren(menulist.firstChild, bundle);
- ]]>
- </body>
- </method>
- <constructor>
- <![CDATA[
- // initialize strings
- var bundle = srGetStrBundle("chrome://messenger/locale/messenger.properties");
-
- // intialize the priority picker
- this.initialize(document.getAnonymousNodes(this)[1], bundle);
-
- // initialize the status picker
- this.initialize(document.getAnonymousNodes(this)[2], bundle);
-
- // initialize the date picker
- var datePicker = document.getAnonymousNodes(this)[3];
- var searchAttribute = this.searchAttribute;
- var nsMsgSearchAttrib = Components.interfaces.nsMsgSearchAttrib;
- var time;
- if (searchAttribute == nsMsgSearchAttrib.Date)
- time = datePicker.value;
- else
- time = new Date();
- // do .value instead of .setAttribute("value", xxx);
- // to work around for bug #179412
- // (caused by bug #157210)
- //
- // the searchvalue widget has two textboxes
- // one for text, one as a placeholder for a date / calendar widget
- datePicker.value = convertDateToString(time);
-
- // initialize the address book picker
- this.initialize(document.getAnonymousNodes(this)[4], bundle);
-
- // initialize the label picker....
- var labelStrings = GetLabelStrings();
- var children = document.getAnonymousNodes(this)[5].firstChild.childNodes;
- // set the label string on each label element...
- for (var index = 0; index < 6; index++)
- children[index].setAttribute('label', labelStrings[index]);
-
- // initialize the junk status picker
- this.initialize(document.getAnonymousNodes(this)[6], bundle);
-
- // initialize the has attachment status picker
- this.initialize(document.getAnonymousNodes(this)[7], bundle);
- ]]>
- </constructor>
- </implementation>
- <handlers>
- <handler event="keypress" keycode="VK_RETURN" action="onEnterInSearchTerm();"/>
- </handlers>
- </binding>
- <binding id="searchterm" name="searchTerm" extends="xul:box">
- <implementation>
- <field name="internalSearchTerm">null</field>
- <field name="internalBooleanAnd">null</field>
- <!-- the actual nsIMsgSearchTerm object -->
- <property name="searchTerm" onget="return this.internalSearchTerm">
- <setter>
- <![CDATA[
- this.internalSearchTerm = val;
-
- var term = val;
- // val is a nsIMsgSearchTerm
- var searchAttribute=this.searchattribute;
- var searchOperator=this.searchoperator;
- var searchValue=this.searchvalue;
-
- // now reflect all attributes of the searchterm into the widgets
- if (searchAttribute) searchAttribute.value = term.attrib;
- if (searchOperator) searchOperator.value = val.op;
- if (searchValue) searchValue.value = term.value;
-
- this.booleanAnd = val.booleanAnd;
- ]]>
- </setter>
- </property>
-
- <property name="searchScope">
- <getter>
- <![CDATA[
- var searchAttribute = this.searchattribute;
- if (searchAttribute)
- return searchAttribute.searchScope;
- return undefined;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- var searchAttribute = this.searchattribute;
- if (searchAttribute) searchAttribute.searchScope=val;
- ]]>
- </setter>
- </property>
- <!-- the three tags that make up a term - to use, set the
- attribute in the XUL to the ID of the term.
- -->
- <property name="searchattribute"
- onget="return document.getElementById(this.getAttribute('searchattribute'));"
- onset="this.setAttribute('searchattribute',val.id)"/>
-
- <property name="searchoperator"
- onget="return document.getElementById(this.getAttribute('searchoperator'));"
- onset="this.setAttribute('searchoperator',val.id)"/>
-
- <property name="searchvalue"
- onget="return document.getElementById(this.getAttribute('searchvalue'));"
- onset="this.setAttribute('searchvalue',val.id)"/>
- <field name="booleanNodes">
- <![CDATA[
- null;
- ]]>
- </field>
- <field name="stringBundle">
- <![CDATA[
- srGetStrBundle("chrome://messenger/locale/search.properties");
- ]]>
- </field>
- <property name="booleanAnd" onget="return this.internalBooleanAnd">
- <setter>
- <![CDATA[
- // whenever you set this, all nodes in booleanNodes
- // are updated to reflect the string
-
- if (this.internalBooleanAnd == val) return;
- this.internalBooleanAnd = val;
-
- var booleanNodes = this.booleanNodes;
- if (!booleanNodes) return;
-
- var stringBundle = this.stringBundle;
- var andString = val ? "And" : "Or";
- for (var i=0; i<booleanNodes.length; i++) {
- try {
- var staticString =
- stringBundle.GetStringFromName("search" + andString + i);
- if (staticString && staticString.length>0)
- booleanNodes[i].setAttribute("value", staticString);
- } catch (ex) { /* no error, means string not found */}
- }
- ]]>
- </setter>
- </property>
- <method name="save">
- <body>
- <![CDATA[
- var searchTerm = this.searchTerm;
- searchTerm.attrib = this.searchattribute.value;
- if (this.searchAttribute > nsMsgSearchAttrib.OtherHeader && this.searchAttribute < nsMsgSearchAttrib.kNumMsgSearchAttributes)
- searchTerm.arbitraryHeader = this.searchattribute.label;
- searchTerm.op = this.searchoperator.value;
- if (this.searchvalue.value)
- this.searchvalue.save();
- else
- this.searchvalue.saveTo(searchTerm.value);
- searchTerm.value = this.searchvalue.value;
- searchTerm.booleanAnd = this.booleanAnd;
- ]]>
- </body>
- </method>
- <!-- if you have a search term element with no search term -->
- <method name="saveTo">
- <parameter name="searchTerm"/>
- <body>
- <![CDATA[
- this.internalSearchTerm = searchTerm;
- this.save();
- ]]>
- </body>
- </method>
- </implementation>
- </binding>
-
- <!-- Folder picker helper widgets -->
- <binding id="popup-base" extends="chrome://global/content/bindings/popup.xml#popup">
- <implementation>
- <field name="tree" readonly="true">
- document.getAnonymousNodes(this)[0];
- </field>
- <method name="updateHover">
- <parameter name="event"/>
- <body>
- <![CDATA[
- var box = this.tree.boxObject;
- if (event.originalTarget == box.treeBody) {
- // XXXbz We really want client*, but event.client* is bogus inside a popup!
- var eventX = event.screenX - document.documentElement.boxObject.screenX;
- var eventY = event.screenY - document.documentElement.boxObject.screenY;
- box.view.selection.select(box.getRowAt(eventX, eventY));
- }
- ]]>
- </body>
- </method>
- <method name="fire">
- <body>
- <![CDATA[
- this.hidePopup();
- if (this.tree.currentIndex >= 0) {
- this.setAttribute("uri", this.tree.builderView.getResourceAtIndex(this.tree.currentIndex).Value);
- this.doCommand();
- }
- ]]>
- </body>
- </method>
- <method name="onBlurMenuList">
- <parameter name="event"/>
- <body>
- <![CDATA[
- this.boxObject.QueryInterface(Components.interfaces.nsIMenuBoxObject).openMenu(false);
- ]]>
- </body>
- </method>
- <field name="onKeyDownMenuList" readonly="true">
- <![CDATA[
- ({
- parentNode: this.parentNode,
- handleEvent: function handleEvent(event) {
- if (this.parentNode.hasAttribute("open"))
- event.stopPropagation();
- }
- })
- ]]>
- </field>
- <field name="onKeyPressMenuList" readonly="true">
- <![CDATA[
- ({
- self: this,
- tree: this.tree,
- parentNode: this.parentNode,
- getLastVisibleRow: function getLastVisibleRow(box) {
- var f = box.getFirstVisibleRow();
- var p = box.getPageCount();
- var l = box.view.rowCount;
- return (l < f + p ? l : f + p) - 1;
- },
- handleEvent: function handleEvent(event) {
- if (event.altKey)
- return;
- var index;
- var box = this.tree.treeBoxObject;
- if (this.parentNode.hasAttribute("open")) {
- event.stopPropagation();
- switch (event.keyCode) {
- case event.DOM_VK_ESCAPE:
- this.self.hidePopup();
- return;
- case event.DOM_VK_ENTER:
- case event.DOM_VK_RETURN:
- this.self.fire();
- return;
- }
- index = this.tree.currentIndex;
- } else {
- switch (event.keyCode) {
- case event.DOM_VK_PAGE_UP:
- case event.DOM_VK_PAGE_DOWN:
- return;
- }
- index = this.self.setInitialSelection();
- }
- switch (event.keyCode) {
- case event.DOM_VK_UP:
- if (index <= 0)
- return;
- index--;
- break;
- case event.DOM_VK_DOWN:
- index++;
- if (index == box.view.rowCount)
- return;
- break;
- case event.DOM_VK_PAGE_UP:
- if (index == box.getFirstVisibleRow())
- box.scrollByPages(-1);
- index = box.getFirstVisibleRow();
- break;
- case event.DOM_VK_PAGE_DOWN:
- if (index == this.getLastVisibleRow(box))
- box.scrollByPages(1);
- index = this.getLastVisibleRow(box);
- break;
- case event.DOM_VK_HOME:
- index = 0;
- break;
- case event.DOM_VK_END:
- index = box.view.rowCount - 1;
- break;
- default:
- return;
- }
- box.view.selection.select(index);
- if (this.parentNode.hasAttribute("open"))
- box.ensureRowIsVisible(index);
- else
- this.self.fire();
- }
- })
- ]]>
- </field>
- <method name="setInitialSelection">
- <body>
- <![CDATA[
- var view = this.tree.view;
- view.selection.selectEventsSuppressed = true;
- for (var i = 0; i < view.rowCount; i++) {
- if (view.isContainer(i)) {
- if (view.isContainerEmpty(i) == view.isContainerOpen(i))
- view.toggleOpenState(i);
- if (view.isContainerOpen(i)) {
- if (i + 1 == view.rowCount ||
- view.getLevel(i + 1) <= view.getLevel(i)) {
- view.toggleOpenState(i);
- }
- }
- }
- }
- var index = -1;
- var uri = this.parentNode.getAttribute("uri");
- if (uri) {
- var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
- index = view.getIndexOfResource(RDF.GetResource(uri));
- }
- view.selection.select(index);
- return index;
- ]]>
- </body>
- </method>
- <constructor>
- <![CDATA[
- this.parentNode.addEventListener("keypress", this.onKeyPressMenuList, true);
- ]]>
- </constructor>
- <destructor>
- <![CDATA[
- this.parentNode.removeEventListener("keypress", this.onKeyPressMenuList, true);
- ]]>
- </destructor>
- </implementation>
- <handlers>
- <handler event="mousemove" action="this.updateHover(event);"/>
- <handler event="click" action="this.updateHover(event);this.fire();"/>
- <handler event="popupshowing">
- <![CDATA[
- this.parentNode.addEventListener("blur", this.onBlurMenuList, false);
- window.top.document.addEventListener("keydown", this.onKeyDownMenuList, true);
- window.top.document.addEventListener("keypress", this.onKeyPressMenuList, true);
- var box = this.tree.treeBoxObject;
- box.focused = true;
- var index = this.setInitialSelection();
- var height = box.view.rowCount * box.rowHeight;
- height += this.boxObject.height - box.treeBody.boxObject.height;
- this.height = height;
- if (index >= 0)
- setTimeout(function() { box.ensureRowIsVisible(index); }, 0);
- ]]>
- </handler>
- <handler event="popuphiding">
- <![CDATA[
- this.parentNode.removeEventListener("blur", this.onBlurMenuList, false);
- window.top.document.removeEventListener("keydown", this.onKeyDownMenuList, true);
- window.top.document.removeEventListener("keypress", this.onKeyPressMenuList, true);
- ]]>
- </handler>
- </handlers>
- </binding>
-
- <binding id="folderTargetPopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
- <xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
- <treecols>
- <treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
- </treecols>
- <treechildren class="foldersTreeChildren"/>
- <template>
- <rule nc:CanFileMessagesOnServer="true" nc:CanFileMessages="true" nc:CanSearchMessages="true">
- <treechildren>
- <treeitem uri="rdf:*">
- <treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
- <treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeSimpleName"
- properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder isServer-rdf:http://home.netscape.com/NC-rdf#IsServer isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
- </treerow>
- </treeitem>
- </treechildren>
- </rule>
- <rule nc:CanFileMessagesOnServer="true" nc:CanFileMessages="false" nc:CanSearchMessages="true" nc:Virtual="false">
- <treechildren>
- <treeitem uri="rdf:*">
- <treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
- <treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeSimpleName"
- properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder isServer-rdf:http://home.netscape.com/NC-rdf#IsServer isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
- </treerow>
- </treeitem>
- </treechildren>
- </rule>
- <rule nc:CanFileMessagesOnServer="true" nc:CanFileMessages="true" nc:Virtual="false">
- <treechildren>
- <treeitem uri="rdf:*">
- <treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
- <treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeSimpleName"
- properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder isServer-rdf:http://home.netscape.com/NC-rdf#IsServer isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
- </treerow>
- </treeitem>
- </treechildren>
- </rule>
- </template>
- </tree>
- </xbl:content>
- </binding>
-
- <binding id="locationpopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
- <xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <tree class="foldersTree" flex="1" datasources="rdf:null" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
- <treecols>
- <treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
- </treecols>
- <treechildren class="foldersTreeChildren"/>
- <template>
- <rule>
- <treechildren>
- <treeitem uri="rdf:*">
- <treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
- <treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeName"
- properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder biffState-rdf:http://home.netscape.com/NC-rdf#BiffState isServer-rdf:http://home.netscape.com/NC-rdf#IsServer newMessages-rdf:http://home.netscape.com/NC-rdf#NewMessages hasUnreadMessages-rdf:http://home.netscape.com/NC-rdf#HasUnreadMessages isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
- </treerow>
- </treeitem>
- </treechildren>
- </rule>
- </template>
- </tree>
- </xbl:content>
- </binding>
-
- <binding id="searchpopup" extends="chrome://messenger/content/mailWidgets.xml#popup-base">
- <xbl:content xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
- <tree class="foldersTree" flex="1" datasources="rdf:msgaccountmanager rdf:mailnewsfolders" ref="msgaccounts:/" flags="dont-build-content" selstyle="primary" hidecolumnpicker="true">
- <treecols>
- <treecol flex="1" primary="true" sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true" sortActive="true" sortDirection="ascending" crop="center" hideheader="true"/>
- </treecols>
- <treechildren class="foldersTreeChildren"/>
- <template>
- <rule nc:CanSearchMessages="true" nc:Virtual="false">
- <treechildren>
- <treeitem uri="rdf:*">
- <treerow sort="rdf:http://home.netscape.com/NC-rdf#FolderTreeName?sort=true">
- <treecell label="rdf:http://home.netscape.com/NC-rdf#FolderTreeSimpleName"
- properties="folderNameCol specialFolder-rdf:http://home.netscape.com/NC-rdf#SpecialFolder isServer-rdf:http://home.netscape.com/NC-rdf#IsServer isSecure-rdf:http://home.netscape.com/NC-rdf#IsSecure serverType-rdf:http://home.netscape.com/NC-rdf#ServerType noSelect-rdf:http://home.netscape.com/NC-rdf#NoSelect"/>
- </treerow>
- </treeitem>
- </treechildren>
- </rule>
- </template>
- </tree>
- </xbl:content>
- </binding>
-
- </bindings>
-